#!/usr/bin/perl

use strict;
use warnings;


my $IFTAB = "/etc/iftab";
my $RULES = "/etc/udev/rules.d/70-persistent-net.rules";


#-----------------------------------------------------------------------------#
# Sanity check
#-----------------------------------------------------------------------------#
die "$IFTAB does not exist to convert\n" unless -f $IFTAB;
die "$RULES already exists\n" if -f $RULES;


#-----------------------------------------------------------------------------#
# Parse /etc/iftab
#-----------------------------------------------------------------------------#

open IFTAB, $IFTAB
    or die "Unable to open $IFTAB: $!";
open RULES, ">$RULES"
    or die "Unable to open $RULES: $!";

print RULES "# This file maintains persistent names for network interfaces.\n";
print RULES "# See udev(7) for syntax.\n";
print RULES "#\n";
print RULES "# Entries are automatically added by the 75-persistent-net-generator.rules\n";
print RULES "# file; however you are also free to add your own entries.\n\n";

my @lines;
while (<IFTAB>) {
    push @lines, $_;

    chomp;
    s/^\s*//;

    next if /^\#/;
    next unless length;

    my ($iface, $selectors) = split /\s/, $_, 2;
    next unless $selectors;

    my @rules;
    while ($selectors) {
	my ($selector, $value, $remainder) = split /\s/, $selectors, 3;
	last unless $selector;
	last unless $value;
	$selectors = $remainder;

	if ($selector =~ /^SYSFS\{([^\}]*)\}$/) {
	    push @rules, "ATTRS{$1}==\"$value\"";
	} elsif ($selector =~ /^driver$/) {
	    push @rules, "DRIVERS==\"$value\"";
	} elsif ($selector =~ /^bus$/) {
	    push @rules, "SUBSYSTEMS==\"$value\"";
	} elsif ($selector =~ /^businfo$/) {
	    push @rules, "ATTR{device}==\"$value\"";
	} elsif ($selector =~ /^(mac|address)$/) {
	    push @rules, "ATTRS{address}==\"" . lc($value) . "\"";
	} elsif ($selector =~ /^(arp|linktype)$/) {
	    push @rules, "ATTRS{type}==\"$value\"";
	}
    }

    next unless @rules;

    print RULES "# Converted from $IFTAB on upgrade\n";
    print RULES join(", ", "SUBSYSTEM==\"net\"", "DRIVERS==\"?*\"", @rules,
		     "NAME=\"$iface\"") . "\n";
    print RULES "\n";
}

close RULES
    or warn "Error while closing $RULES: $!";
close IFTAB
    or warn "Error while closing $IFTAB: $!";


open IFTAB, ">$IFTAB"
    or die "Unable to open $IFTAB: $!";

print IFTAB "# This file is no longer used and has been automatically replaced.\n";
print IFTAB "# See $RULES for more information.\n";
print IFTAB "#\n\n";

foreach my $line (@lines) {
    $line =~ s/^(\s*)/$1\#/ if $line !~ /^\s*\#/;
    print IFTAB $line;
}

close IFTAB
    or warn "Error while closing $IFTAB: $!";
